<template>
  <AForm
    ref="form"
    :model="model"
    :layout="layout"
    :style="{
      '--form-gap': gap / 2 + 'px',
      '--form-item-width': 100 / cols + '%',
      'margin-left': -gap / 2 + 'px',
      'margin-right': -gap / 2 + 'px',
    }"
    :class="$style.form"
  >
    <component
      :is="getItemWidget(field)"
      v-for="field in fields"
      :field="field"
      :key="field.prop"
      :path="field.type == 'layout' ? [] : [field.prop]"
    />
    <slot></slot>
  </AForm>
</template>
<script>
import { Form as AForm } from 'ant-design-vue';
import DiFormItem from './DiFormItem.vue';
import { widgets } from './form';
export default {
  components: { AForm, DiFormItem },
  props: {
    widgets: {
      type: Object,
      default: () => ({}),
    },
    extra: {
      type: Object,
      default: () => ({}),
    },
    model: {
      type: Object,
      default: () => ({}),
    },
    fields: {
      type: Array,
      default: () => [],
    },
    cols: {
      type: Number,
      default: 3,
    },
    gap: {
      type: Number,
      default: 32,
    },
    layout: {
      type: String,
      default: 'vertical',
    },
    display: {
      type: Boolean,
      default: false,
    },
  },
  data() {
    return {};
  },
  provide() {
    return { DiFormContext: this };
  },
  mounted() {},
  methods: {
    getItemWidget(field) {
      if (field.type == 'layout') {
        return this.widgets[field.widget] || widgets[field.widget];
      }
      return DiFormItem;
    },
    getWidget(field, defaultWidget = 'input') {
      let display = field.display !== undefined ? field.display : this.display;

      let widget = field.widget;
      let myWidgets = Object.assign({}, this.widgets, widgets);
      if (!widget) {
        widget = defaultWidget;
      }
      if (display) {
        widget =
          ['input', 'number', 'textarea', 'date', 'selectUser'].indexOf(widget) > -1
            ? 'display'
            : widget;
        return myWidgets[field.displayWidget || widget];
      }
      return myWidgets[widget] || widget;
    },
    validate(...args) {
      return this.$refs.form.validate(...args);
    },
    clearValidate(...args) {
      return this.$refs.form.clearValidate(...args);
    },
  },
};
</script>
<style lang="scss" module>
.form {
  box-sizing: border-box;
}
</style>
